package com.hsc.box;

/**
 * 思考的问题：添加这个中间层抽象类的目的？
 * 我们在接口中抽出了一层，关于整个Box体系需要提供的方法（能力），这样不但可以用户使用起来更加的方便，也给后续的如果产生新的工具类，有了一个良好的约束。
 * 但是有一个不好的地方，如果子类直接进行实现最上层的接口，就必须要实现所有的抽象方法，这对于后续的子类（扩展类）并不是很友好。
 * 添加这个中间层抽象类的目的
 * 这时我们使用抽象类能够很好解决这个问题，可以对接口的方法进行实现，自己本身也可以定义抽象方法，如果最终的实现类继承了该抽象方法，只需要实现最主要的功能即可，提供最主要的能力。
 * 这里也很好体现了一个设计模式的思想：缺省适配器模式
 * 也体现了面向对象的三大特性：封装、继承、多态
 */
public abstract class AbstractBox<T> implements Box<T> {

    //声明一个子类共有的属性
    private int size;


    /**
     * 【主要的方法】：规定一个标准，添加的一个元素的方法，如果子类或实现也属于Box的这个体系，就必须有添加元素的这个能力
     * public abstract 权限修饰符和特征修饰符接口默认携带的，可以写也可以不写
     *
     * @param element
     * @return
     */
    public abstract boolean add(T element);

    /**
     * 【主要方法】：接口中定义了一个标准，查询的方法：根据索引的下标，获取到对应的元素
     *
     * @param index
     * @return
     */
    public abstract T get(int index); //抽象类这一层这个方法，可以写也可以不写，如果具体的类实现了AbstractBox<T>，就必须实现Box<T>接口的主要的方法


    /**
     * 【主要方法】：接口中定义了一个标准，删除一个元素的方法：根据索引的下标，删除对应元素。如果子类或实现也属于Box的这个体系，就必须有添加元素的这个能力
     *
     * @param index
     * @return
     */
    public abstract T remove(int index);//抽象类这一层这个方法，可以写也可以不写，如果具体的类实现了AbstractBox<T>，就必须实现Box<T>接口的主要的方法

    /**
     * 【子类中共有的方法】：如果我们顶层接口中，没有设计有这个size方法，但是我们的子类中都有这个方法，此时我们就可以将该方法抽到这里来，可以避免代码的冗余
     *
     * @return
     */
    public  int size(){
        return size;
    };

    /**
     * 【非主要方法】：指定位置，添加指定元素的方法，如果这个方法不是整个Box体系中必须提供的能力，我们可以不一定在接口中强制规定，因为接口中规定了，实现类进行实现了，就必须实现该方法
     *
     * @param index
     * @param element
     * @return
     */
    public abstract boolean add(int index, T element);//抽象类这一层这个方法，可以写也可以不写，如果具体的类实现了AbstractBox<T>，就必须实现Box<T>接口的主要的方法


    /**
     * 【非主要方法】添加整个容器的方法：我们将接口中非主要实现功能或者说是后续规划要实现的功能，放在抽象类这一层做实现，
     * 这样我们的具体继承我们的抽象类的时候，只需要实现接口中定义的主要方法就可以了
     *
     * @param box
     * @return
     */
    public boolean addAll(Box<T> box) {
        throw  new NuSupportedOperationException();
    }

    /**
     * 【非主要方法】在指定的位置，添加所有元素的方法，个方法也不是子类中必须要实现，或者说是后续规划要实现的功能,放在抽象类这一层做实现，
     * 这样我们的具体继承我们的抽象类的时候，只需要实现接口中定义的主要方法就可以了
     *
     * @param index
     * @param box
     * @return
     */
    public boolean addAll(int index, Box<T> box) {
       throw new NuSupportedOperationException();
    }


    /**
     * 再且，我们这里还可以添加一些子类共有的方法，但是父类接口中没有进行规定的
     */
}
